# -*- coding: utf-8 -*-
# @Time     : 2020/8/17 14:15
# @Author   : iTreeNewBee
# @File     : ObjectApprove.py
# @Project  : 联调测试平台----循环所有待审核案例审批
from selenium import webdriver
import time
import base64
from time import sleep
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By
from HWOcrClientAKSK import HWOcrClientAKSK
import sys
import LogClass
from setting import *


#只有一级标签的节点特殊处理
special = ['双跨融合通信多媒体会议新增会议并发包月功能',
           '区块链数据一致性', '千里眼新增一脸通行业标签需求',
           '工业互联网平台产品', '新增多媒体会议产品支持个付功能',
           '运管全面结算优化需求', '企业阅读迁移到集客大厅',
           '物联网优化需求',
           '业务重发归档',
           '和教育迁移至集客大厅']
#日志对象
log = LogClass.Loggings()
#代码行数
# line = sys._getframe().f_lineno


def isElementExist(driver, elements):
    """
    :param driver:  浏览器驱动
    :param elements: 元素classname定位方法
    :return:  type bool ，True or False
    """
    try:
        driver.find_element_by_class_name(elements)
        return True
    except:
        return False


def count_fun(func):
    """
    统计函数执行次数及时间
    :param func:
    :return:
    """
    num = 0  # 初始化次数
    total_time = 0
    def call_fun(*args, **kwargs):
        nonlocal num  # 声明num 变当前作用域局部变量为最临近外层（非全局）作用域变量。
        global TOTAL_TIME, NUM
        # global NUM
        start = time.time()  # 代码执行开始时间
        num += 1  # 每次调用次数加1
        NUM = num
        func(*args, **kwargs)  # 原函数
        end = time.time()  # 代码执行结束时间
        longtime = end - start + total_time
        TOTAL_TIME = longtime
        # print("此函数被调用%s次，本次调用花费时间：%s" % (num, longtime))

    return call_fun


def get_code(img_path):
    """
    传入图片路径获取验证码,AK,SK替换成自己的密钥
    :param img_path:
    :return: code
    """
    AK = MYAK
    SK = MYSK
    region = "cn-north-4"
    req_uri = "/v1.0/ocr/general-text"
    img_path = img_path
    option = {}
    try:
        ocr_client = HWOcrClientAKSK(AK, SK,
                                     region)
        response = ocr_client.request_ocr_service_base64(req_uri, img_path,
                                                         option)
        # print(response.json()['result'])
        words = response.json()['result']['words_block_list'][0]['words']
        code = ''.join(list(filter(str.isalnum, str(words).replace(' ', ''))))
        return code
    except ValueError as e:
        log.error(f'line:{sys._getframe().f_lineno} ' + str(e))

def get_codeimg(img_base64):
    """
    下载验证码图片
    :param img_base64:
    :return:
    """
    imagedata = base64.b64decode(img_base64)
    file = open('code.jpg', "wb")
    file.write(imagedata)
    file.close()


def search(dict, search_str):
    """
    根据输入匹配values
    :param dict:
    :param search_str:
    :return:
    """
    d = dict
    for key, values in d.items():
        # print(key, values)
        if search_str in key:
            return values
    print("输入的项目没有被找到，请仔细检查...")


def find(driver, by, expr):
    """
    定位元素并高亮
    :param driver:
    :param by:
    :param expr:
    :return:
    """
    global element
    try:
        element = driver.find_element(by, expr)
        driver.execute_script("arguments[0].setAttribute('style', arguments[1]);", element)
    except:
        return element
    return element


def login():
    """
    登录联调测试大厅
    :return:
    """
    global code_input
    options = webdriver.ChromeOptions()
    #无头模式，页面调试可注释掉
    options.add_argument('--headless')
    browers = webdriver.Chrome(chrome_options=options)
    browers.maximize_window()
    browers.implicitly_wait(15)
    browers.get('http://10.248.62.90:8080/#/')
    try:
        WebDriverWait(browers, 1).until(EC.presence_of_element_located((By.NAME, 'name')))
    except Exception as e:
        log.error(f'line:{sys._getframe().f_lineno} ' + str(e))
        browers.implicitly_wait(30)
    try:
        # 账号密码
        browers.find_element_by_id('name').send_keys(USERNAME)
        browers.find_element_by_id('pwd').send_keys(PASSWD)
    except:
        print('登录联调测试平台失败')
        raise
    try:
        WebDriverWait(browers, 1).until(EC.presence_of_element_located((By.ID, 'code_img')))
    except Exception as e:
        log.error(f'line:{sys._getframe().f_lineno} ' + str(e))
        sleep(1)
    sleep(2)
    try:
        # 获取验证码图片base64
        base64_img = browers.find_element_by_id('code_img').get_property('src').split(',')[1]
        get_codeimg(base64_img)
        code = get_code('code.jpg')
        code_input = find(browers, 'id', 'codeInput')
        code_input.send_keys(code)
        find(browers, 'id', 'submit_btn').click()
    except:
        pass
    try:
        WebDriverWait(browers, 1).until(EC.presence_of_element_located((By.CLASS_NAME, 'el-message-box')))
    except Exception as e:
        log.error(f'line:{sys._getframe().f_lineno} ' + str(e))
        sleep(3)
    flag = isElementExist(browers, 'el-message-box')
    while flag:
        try:
            WebDriverWait(browers, 5, 0.5).until(EC.presence_of_element_located((By.XPATH, '//button/span[text()[contains(.,"确定")]]')))
            WebDriverWait(browers, 5, 0.5).until(EC.element_to_be_clickable((By.XPATH, '//button/span[text()[contains(.,"确定")]]')))
        except Exception as e:
            log.error(f'line:{sys._getframe().f_lineno} ' + str(e))
            sleep(1)
        try:
            browers.find_element_by_xpath('//button/span[text()[contains(.,"确定")]]').click()
            sleep(1)
            code_input.clear()
            base64_img = find(browers, 'id', 'code_img').get_property('src').split(',')[1]
            get_codeimg(base64_img)
            code = get_code('code.jpg')
            sleep(1)
            code_input.send_keys(code)
            find(browers, 'id', 'submit_btn').click()
            sleep(3)
        except:
            pass
        try:
            WebDriverWait(browers, 5, 0.5).until(EC.presence_of_element_located((By.CLASS_NAME, 'icon_logout')))
        except Exception as e:
            log.error(f'line:{sys._getframe().f_lineno} ' + str(e))
            continue
        is_login = isElementExist(browers, 'icon_logout')
        if is_login:
            break
    log.info('联调测试平台登录成功')
    return browers


def level1(driver, root_label):
    """
    返回一级菜单字典level1
    :param driver:浏览器驱动
    :param root_label:测试执行下的跟节点，例如"集客大厅"和"一级boss"
    :return: 返回一级菜单字典level1
    """
    driver = driver
    try:
        WebDriverWait(driver, 3).until(EC.presence_of_element_located((By.ID, 'tree_1_ul')))
    except:
        sleep(3)
    eiv_html = find(driver, 'id', root_label).get_attribute('outerHTML')
    list = str(eiv_html).split('<li')
    level1 = {}
    for i in list:
        tag_a = i.split('<a')
        tag_b = ''.join(''.join(tag_a[1:]).split('><span')[:1])
        if len(tag_b) > 2:
            tag_c = tag_b.split('"')
            # 将所有level1的id和title加入字典中
            level1.update({tag_c[13]: tag_c[1][:-2]})
    log.info(f'获取集客大厅下所有项目字典:{level1}')
    return level1


def level2(driver, tree):
    """
    返回二级菜单字典level2
    :param driver:
    :param tree:
    :return:
    """
    driver = driver
    try:
        WebDriverWait(driver, 3).until(EC.presence_of_element_located((By.ID, tree + '_ul')))
    except:
        sleep(3)
    evi_html = driver.find_element_by_id(tree + '_ul').get_attribute('outerHTML')
    # print(evi_html)
    list = str(evi_html).split('<li')
    level2 = {}
    for i in list:
        tag_a = i.split('<a')
        tag_b = ''.join(''.join(tag_a[1:]).split('><span')[:1])
        if len(tag_b) > 2:
            tag_c = tag_b.split('"')
            # 将所有level1的id和title加入字典中
            level2.update({tag_c[13]: tag_c[1][:-2]})
    log.info(f'获取分类下所有项目字典:{level2}')
    return level2


def approve(browers, approved):
    """
    approved:审批的节点
    """
    while True:
        # 打开搜索出来的结果
        sleep(10)
        try:
            WebDriverWait(browers, 3, 0.5).until(EC.presence_of_element_located((By.XPATH,
                                                                            '//*[@id="app"]/div[2]/div[1]/div[1]/div/div[3]/div/div/div[2]/div[1]/div[3]/table/tbody/tr[1]/td[10]')))
        except:
            break
        find_result = find(browers, 'xpath',
                           '//*[@id="app"]/div[2]/div[1]/div[1]/div/div[3]/div/div/div[2]/div[1]/div[3]/table/tbody/tr[1]/td[10]')
        find_result.click()
        try:
            WebDriverWait(browers, 3).until(EC.presence_of_element_located(
                (By.XPATH, '//button/span[text()[contains(.,"提 交")]]')))
        except:
            log.error(f'line:{sys._getframe().f_lineno} ' + str(e))
            sleep(3)
        # 定位提交按钮并拖动滚动条到此元素位置
        try:
            target = find(browers, 'xpath', '//button/span[text()[contains(.,"提 交")]]')
            browers.execute_script("arguments[0].scrollIntoView();", target)
        except:
            windows = browers.window_handles
            browers.switch_to.window(windows[-1])
        try:
            WebDriverWait(browers, 1).until(EC.presence_of_element_located((By.XPATH, '//div[@class="backToBottom"]')))
            backToBottom_ele = find(browers, 'xpath', '//div[@class="backToBottom"]')
            backToBottom_ele.click()
        except:
            sleep(3)
        try:
            WebDriverWait(browers, 3).until(
                EC.presence_of_element_located((By.XPATH, '//div[@class="el-select"]/div/span')))
        except Exception as e:
            sleep(3)
        # 是否通过选择
        resultAudit = find(browers, 'xpath', '//label[text()="结果判定"]/following::input[1]')
        resultAudit.click()
        sleep(1)
        try:
            WebDriverWait(browers, 3).until(
                EC.presence_of_element_located((By.CLASS_NAME, 'el-scrollbar__view el-select-dropdown__list')))
        except:
            sleep(3)
        agree = find(browers, 'xpath',
                     '//ul[@class="el-scrollbar__view el-select-dropdown__list"]/li[2]/span[text()="通过"]')
        agree.click()
        sleep(2)
        # 提交
        commit_ele = find(browers, 'xpath', '//button/span[text()[contains(.,"提 交")]]')
        commit_ele.click()
        try:
            WebDriverWait(browers, 3).until(
                EC.presence_of_element_located((By.XPATH, '//button/span[text()[contains(.,"确定")]]')))
        except:
            sleep(3)
        sleep(1)
        confirm_ele = find(browers, 'xpath', '//button/span[text()[contains(.,"确定")]]')
        confirm_ele.click()
        sleep(15)
        boxbtn_ele = find(browers, 'xpath', '//div[@class="el-message-box__btns"]')
        boxbtn_ele.click()
    log.info(f'-----{approved}审批完成-----')


if __name__ == '__main__':
    log.info('登录联调测试平台')
    # 登录联调测试大厅
    browers = login()
    browers.implicitly_wait(30)
    # 查找一级标签id
    tree1_1 = level1(browers, "tree_1_ul")   #根结点为集客大厅
    tree1_2 = level1(browers, "tree_134_ul") #根结点为一级boss
    root_list = [tree1_1, tree1_2]       #后续如果新增根结点，添加到列表
    for root in root_list:
        log.info('开始循环平台分类')
        # print(root)
        # 一级菜单循环
        for k, v in root.items():
            log.info('循环平台分类下的一级标签')
            sleep(5)
            switch_ele = browers.find_element_by_id(v + '_switch')
            browers.execute_script('arguments[0].click()', switch_ele)
            if k not in special:
                tree2 = level2(browers, v)
            else:
                # tree2 = {k, v} #目前没有一级标签的点击了没有反应，所以直接跳出进入下一循环
                log.error(f'line:{sys._getframe().f_lineno}' + f'点击到失效菜单{k}')
                continue
            # 二级菜单循环
            for key, value in tree2.items():
                log.info('循环分类下二级标签，并查找待审核案例')
                span_ele = browers.find_element_by_id(value + '_span')
                browers.execute_script('arguments[0].click()', span_ele)
                try:
                    WebDriverWait(browers, 3).until(EC.presence_of_element_located((By.CLASS_NAME, 'searchNav')))
                except Exception as e:
                    sleep(1)
                # 定位'待审核'标签并完成搜索
                choose_ele = browers.find_element_by_xpath('//label[text()="用例状态"]//following::input[1]')
                sleep(3)
                try:
                    browers.execute_script('arguments[0].click()', choose_ele)
                    # print('选择下拉菜单点击成功')
                except:
                    log.error(f'line:{sys._getframe().f_lineno} {k}-{key} 点击下拉菜单失败')
                    continue
                sleep(2)
                try:
                    #选择用例状态下拉菜单里的待审核进行查询,这个页面一共有六个div，用例状态是第六个div
                    caseStatuslist = browers.find_elements_by_xpath('//div[@class="el-select-dropdown__wrap el-scrollbar__wrap"]/ul')[5].find_elements_by_tag_name('li')
                    for id,content in enumerate(caseStatuslist):
                        if content.text == '待审核':
                            content.click()
                    # print('待审核点击成功')
                except Exception as e:
                    # print(e)
                    log.error(f'line:{sys._getframe().f_lineno} {k}-{key}--点击待审核失败')
                    continue
                sleep(2)
                #收回下拉菜单
                browers.execute_script('arguments[0].click()', choose_ele)
                sleep(1)
                query_ele = find(browers, 'xpath', '//button/span[text()[contains(.,"查询")]]')
                browers.execute_script('arguments[0].click()', query_ele)
                # print('点击查询按钮。。。')
                # sleep(4)
                try:
                    WebDriverWait(browers, 3).until(EC.presence_of_element_located((By.XPATH,
                                                                                    '/html/body/div[1]/div[2]/div[1]/div[1]/div/div[3]/div/div/div[2]/div[1]/div[3]/table/tbody/tr[1]/td[9]/div/span[text()="待审核"]')))
                except Exception as e:
                    # print('没有定位到审核元素，continue下一节点')
                    # 将刚选择的信息进行重置后进入下一个选项
                    restart_ele = find(browers, 'xpath', '//button/span[text()[contains(.,"重置")]]')
                    browers.execute_script('arguments[0].click()', restart_ele)
                    sleep(0.5)
                    log.info(f'{k}-{key}--无待审核案例，进入下一标签查找')
                    continue
                # 开始审批
                try:
                    log.info(f'{k}--{key}--开始审批')
                    approve(browers, key)
                except:
                    # print('二级菜单审批完成')
                    # 审批完成后进行重置后进入下一个选项
                    restart_ele = find(browers, 'xpath', '//button/span[text()[contains(.,"重置")]]')
                    browers.execute_script('arguments[0].click()', restart_ele)
                    continue
                break  # 二级菜单审批完成跳出二级循环
    log.info('审批结束')
    browers.quit()